﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;

namespace Common.Buffer
{

    public class MaplePacketWrite : IDisposable,MaplePacket
    {

        MemoryStream stream = null;
        BinaryWriter Writer = null;

        public MaplePacketWrite(SendPacketOpcode Send)
        {
            stream = new MemoryStream();
            Writer = new BinaryWriter(stream);
            Write((byte)Send);
        }


        public void Dispose()
        {
            if (Writer != null) Writer.Close();

            stream.Close();
            Writer = null;
            stream = null;
        }

        void baosWrite(byte data)
        {
            Writer.Write(data);
        }


        public void WriteZero(int i)
        {
            for (int x = 0; x < i; x++)
            {
                baosWrite((byte)0);
            }
        }

        public void Write(byte[] b)
        {
            for (int x = 0; x < b.Length; x++)
            {
                baosWrite(b[x]);
            }
        }

        public void Write(byte b)
        {
            baosWrite(b);
        }

        public void Write(int b)
        {
            baosWrite((byte)b);
        }

        public void WriteShort(short i)
        {
            baosWrite((byte)(i & 0xFF));
            baosWrite((byte)(i >> 8 & 0xFF));
            //log("\r\n");
        }

        public void WriteShort(int i)
        {
            baosWrite((byte)(i & 0xFF));
            baosWrite((byte)(i >> 8 & 0xFF));
            //log("\r\n");
        }

        public void WriteInt(int i)
        {
            baosWrite((byte)(i & 0xFF));
            baosWrite((byte)(i >> 8 & 0xFF));
            baosWrite((byte)(i >> 16 & 0xFF));
            baosWrite((byte)(i >> 24 & 0xFF));
            //log("\r\n");
        }

        public void WriteReversedInt(long l)
        {
            baosWrite((byte)(int)(l >> 32 & 0xFF));
            baosWrite((byte)(int)(l >> 40 & 0xFF));
            baosWrite((byte)(int)(l >> 48 & 0xFF));
            baosWrite((byte)(int)(l >> 56 & 0xFF));
            //log("\r\n");
        }

        public void WriteAsciiString(String s)
        {
            Write(Encoding.ASCII.GetBytes(s));
            //log("\r\n");
        }

        public void WriteAsciiString(String s, int max)
        {
            if (Encoding.ASCII.GetBytes(s).Length > max)
            {
                s = s.Substring(0, max);
            }
            Write(Encoding.ASCII.GetBytes(s));
            for (int i = Encoding.ASCII.GetBytes(s).Length; i < max; i++)
            {
                baosWrite((byte)0);
            }
            //log("(长度:" + (max - s.getBytes(ASCII).length) + ")");
            //log("\r\n\r\n");
        }

        public void WriteMapleNameString(String s)
        {
            if (Encoding.ASCII.GetBytes(s).Length > 12)
            {
                s = s.Substring(0, 12);
            }
            WriteAsciiString(s);
            for (int x = Encoding.ASCII.GetBytes(s).Length; x < 12; x++)
            {
                baosWrite((byte)0);
            }
            //log("(长度:" + (12 - s.getBytes(ASCII).length) + ")");
            //log("\r\n\r\n");
        }

        public void WriteMapleAsciiString(String s)
        {
            if (s == null)
            {
                WriteShort(0);
                return;
            }
            WriteShort((short)Encoding.ASCII.GetBytes(s).Length);
            WriteAsciiString(s);
        }

        public void WriteMapleAsciiString(String[] s)
        {
            int len = 0;
            foreach (String str in s)
            {
                if (str != null)
                {
                    len += Encoding.ASCII.GetBytes(str).Length;
                }
            }
            if (len < 1)
            {
                WriteShort(0);
                return;
            }
            len += s.Length - 1;
            WriteShort((short)len);
            for (int i = 0; i < s.Length; i++)
            {
                if (s[i] != null)
                {
                    WriteAsciiString(s[i]);
                }
                if (i < s.Length - 1)
                {
                    Write(0);
                }
            }
        }

        public void WritePos(Point s)
        {
            WriteShort(s.X);
            WriteShort(s.Y);
        }

        /**
         * 输出一个矩形区域
         * @param s
         */
        public void WriteRect(Rectangle s)
        {
            WriteInt(s.X);
            WriteInt(s.Y);
            WriteInt(s.X + s.Width);
            WriteInt(s.Y + s.Height);
        }

        public void WriteLong(long l)
        {
            baosWrite((byte)(int)(l & 0xFF));
            baosWrite((byte)(int)(l >> 8 & 0xFF));
            baosWrite((byte)(int)(l >> 16 & 0xFF));
            baosWrite((byte)(int)(l >> 24 & 0xFF));
            baosWrite((byte)(int)(l >> 32 & 0xFF));
            baosWrite((byte)(int)(l >> 40 & 0xFF));
            baosWrite((byte)(int)(l >> 48 & 0xFF));
            baosWrite((byte)(int)(l >> 56 & 0xFF));
            //log("\r\n");
        }

        public void WriteReversedLong(long l)
        {
            baosWrite((byte)(int)(l >> 32 & 0xFF));
            baosWrite((byte)(int)(l >> 40 & 0xFF));
            baosWrite((byte)(int)(l >> 48 & 0xFF));
            baosWrite((byte)(int)(l >> 56 & 0xFF));
            baosWrite((byte)(int)(l & 0xFF));
            baosWrite((byte)(int)(l >> 8 & 0xFF));
            baosWrite((byte)(int)(l >> 16 & 0xFF));
            baosWrite((byte)(int)(l >> 24 & 0xFF));
            //log("\r\n");
        }

        public void WriteBool(bool b)
        {
            Write(b ? 1 : 0);
        }


        public byte[] GetPacket()
        {
            byte[] b = stream.ToArray();
            return b;
        }

        public override string ToString()
        {
            return Tools.MapleHexTool.ToStringFromAscii(stream.ToArray());
        }

        public byte[] getBytes()
        {
            return stream.ToArray();
        }
    }
}
